package test.netty.core.chapter1.socket;

import lombok.extern.slf4j.Slf4j;
import test.netty.common.exceptions.NettyException;

import java.io.FileOutputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

/**
 * <p>标题: SocketChannelServerDemo</p>
 * <p>功能描述: </p>
 *
 * <p>创建时间: 2021-04-03,09:18</p>
 * <p>作者：chaiys</p>
 **/
@Slf4j
public class SocketChannelServerDemo {

    public static void main(String[] args) {
        String writeFilePath = "E:\\File\\电脑信息\\aaa.txt";
        try {
            // 1. 服务器通道打开
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 2. 绑定端口号
            serverSocketChannel.bind(new InetSocketAddress(9001));
            log.info("======服务端启动======");
            // 3. 接收文件, 创建文件输出流
            FileOutputStream fileOutputStream = new FileOutputStream(writeFilePath);
            // 4. 创建由内存读到硬盘的通道
            FileChannel fileChannel = fileOutputStream.getChannel();
            // 5. 阻塞连接
            serverSocketChannel.configureBlocking(true);
            // 6. 服务端接收客户端之后一定要记得给返回值，后面都是靠返回值操作的
            SocketChannel accept = serverSocketChannel.accept();
            log.info("======连接完成======");
            // 7. 创建ByteBuffer,来读取接收的数据，堆内
            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
            int size = -1;
            while ((size = accept.read(byteBuffer)) != -1) {
                // 将索引重新指回0
                byteBuffer.clear();
                // 将存入的ByteBuffer对象写入文件输出管道
                fileChannel.write(byteBuffer);
                // 翻转缓冲区
                byteBuffer.flip();
            }
        } catch (Exception e) {
            log.error("服务器异常！", e);
            throw new NettyException("服务器异常！", e);
        }
    }
}
